package com.maimang.platform.crm.controller;

import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse;
import com.dingtalk.api.response.OapiSsoGetuserinfoResponse;
import com.maimang.platform.base.BaseController;
import com.maimang.platform.base.Result;
import com.maimang.platform.common.entity.SysDept;
import com.maimang.platform.common.entity.SysDeptTree;
import com.maimang.platform.common.entity.SysUser;
import com.maimang.platform.common.service.SysDeptService;
import com.maimang.platform.common.service.SysUserService;
import com.maimang.platform.common.utils.ShiroUtils;
import com.maimang.platform.common.utils.http.ServletUtils;
import com.maimang.platform.crm.config.DingTalk;
import com.maimang.platform.crm.service.DingTalkLoginService;
import com.maimang.platform.crm.util.TreeHelper;
import com.maimang.platform.enums.Status;
import com.maimang.platform.lang.StringUtils;
import com.maimang.platform.shiro.realm.UserToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author Rocky
 * @version 1.0.0
 * @类名 SysLoginController
 * @描述 <br>钉钉登录验证</br>
 * @日期 2019-09-28
 * @email jintaozhao@qq.com
 */
// @Api(value = "钉钉登录", description = "钉钉第三方登录接口说明")
@ApiIgnore
@Controller
@RequestMapping("/dingtalk")
public class DingTalkLoginController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(DingTalkLoginController.class);

	@Autowired
	private DingTalkLoginService dingTalkLoginService;

	@Autowired
	private SysUserService sysUserService;

	@Autowired
	private SysDeptService sysDeptService;

	/**
	 * 钉钉扫码登录
	 * 1. 获取临时code
	 * 2. 获取access_token
	 * 3. 获取持久授权码persistent_code
	 * 4. 获取SNS_TOKEN
	 * 5. 获取用户信息
	 *
	 * @param code
	 * @param state
	 * @param modelMap
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/login_qr")
	public void loginByQRcode(@RequestParam(name = "code") String code, @RequestParam(name = "state") String state,
	                          ModelMap modelMap, HttpServletResponse response) throws Exception {
		OapiSnsGetuserinfoBycodeResponse.UserInfo userInfo = dingTalkLoginService.getUserInfoByCode(code);
		String openId = userInfo.getOpenid();
		String unionid = userInfo.getUnionid();

		SysUser user = sysUserService.selectUserByUnionid(unionid, StringUtils.EMPTY);
		if (user != null) {
			UserToken token = new UserToken(user.getLoginName(), user.getUserid(), true);
			doLogin(token, response);
		} else {
			logger.error("====鉴权失败，请检查====");
			Result result = Result.FAIL(Status.authentication_fail);
			ServletUtils.renderString(response, result.toJson());
		}
	}


	/**
	 * 管理后台免登接口
	 *
	 * @param modelMap 前端页面视图
	 * @param response 响应
	 * @param code     从钉钉后台获取的免登授权码
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/ddlogin")
	public void loginWithoutPassword(ModelMap modelMap, HttpServletResponse response, @RequestParam(name = "code", required = false) String code) throws Exception {
		if (StringUtils.isEmpty(code)) {
			logger.info("====code为空，请检查====");
			Result result = Result.FAIL(Status.parameters_incorrect);
			ServletUtils.renderString(response, result.toJson());
		}
		// 第一步：获取免登授权码,即参数code
		// 第二步：获取应用后台免登的accessToken
		// 第三步：获取应用管理员的身份信息
		// 下面这个方法service实现中集成了第二第三步
		OapiSnsGetuserinfoBycodeResponse.UserInfo userInfo = dingTalkLoginService.getUserInfoByCode(code);

		String openId = userInfo.getOpenid();
		String unionid = userInfo.getUnionid();

		SysUser user = sysUserService.selectUserByUnionid(unionid, StringUtils.EMPTY);
		if (user != null) {
			UserToken token = new UserToken(user.getLoginName(), user.getUserid(), true);
			doLogin(token, response);
		} else {
			logger.error("====鉴权失败，请检查====");
			Result result = Result.FAIL(Status.authentication_fail);
			ServletUtils.renderString(response, result.toJson());
		}

		// OapiSsoGetuserinfoResponse ssoGetuserinfoResponse = dingTalkLoginService.getUserInfo(code);
		// if (ssoGetuserinfoResponse.getErrcode() == 0L) {
		// 	OapiSsoGetuserinfoResponse.CorpInfo corpInfo = ssoGetuserinfoResponse.getCorpInfo();
		// 	// OapiSsoGetuserinfoResponse.UserInfo userInfo = ssoGetuserinfoResponse.getUserInfo();
		// 	if (StringUtils.isEmpty(userInfo.getUserid())) {
		// 		logger.error("====钉钉返回数据中无userid，请检查====");
		// 		Result result = Result.FAIL(Status.userid_without);
		// 		ServletUtils.renderString(response, result.toJson());
		// 	} else {
		// 		SysUser sysUser = sysUserService.selectUserByUserid(userInfo.getUserid());
		// 		if (sysUser == null || corpInfo.getCorpid().equals(DingTalk.CorpId)) {
		// 			Result result = Result.FAIL(Status.userid_without);
		// 			logger.error("====数据不正确====");
		// 			ServletUtils.renderString(response, result.toJson());
		// 		} else {
		// 			UserToken token = new UserToken(userInfo.getName(), userInfo.getUserid(), true);
		// 			logger.info("====[钉钉免密码]登录成功，跳转至系统首页====");
		// 			doLogin(token, response);
		// 		}
		// 	}
		// } else {
		// 	Result result = Result.FAIL(Status.userid_without);
		// 	logger.error("====数据不正确====");
		// 	ServletUtils.renderString(response, result.toJson());
		// }
	}

	/**
	 * shiro用户登录
	 *
	 * @param token    用户信息
	 * @param response 响应
	 * @throws IOException
	 */
	private void doLogin(UserToken token, HttpServletResponse response) throws IOException {
		Subject subject = SecurityUtils.getSubject();
		try {
			subject.login(token);
			response.sendRedirect("/index");
		} catch (AuthenticationException e) {
			logger.error("====鉴权失败，请检查====");
			Result result = Result.FAIL(Status.authentication_fail, e);
			ServletUtils.renderString(response, result.toJson());
		}
	}

	/**
	 * 小程序登录
	 * @param code 免登授权码
	 * @param response 响应
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/login")
	@ResponseBody
	public Result login(@RequestParam(name = "code") String code, HttpServletResponse response) throws Exception {
		if (StringUtils.isEmpty(code))
			return error("免登授权码为空");
		// 获取access_token,已在接口内部获取
		// 获取用户userid,钉钉的用户id
		String userid = dingTalkLoginService.getUserid(code);
		// 根据userid查询用户信息
		if (StringUtils.isEmpty(userid))
			return error("该授权码无法获取到用户userid");
		// 登录系统
		SysUser user = sysUserService.selectUserByUserid(userid);

		if (user != null) {
			UserToken token = new UserToken(user.getLoginName(), user.getUserid(), true);
			Subject subject = SecurityUtils.getSubject();
			try {
				subject.login(token);
			} catch (AuthenticationException e) {
				logger.error("====鉴权失败，请检查====");
				Result result = Result.FAIL(Status.authentication_fail);
				ServletUtils.renderString(response, result.toJson());
			}
		} else {
			logger.error("====鉴权失败，请检查====");
			Result result = Result.FAIL(Status.user_without);
			ServletUtils.renderString(response, result.toJson());
		}

		String jwtUserInfoToken = ShiroUtils.getJwtUserInfoToken();
		Map<String, Object> jwtUserInfo = ShiroUtils.getJwtUserInfo();
		// response.setHeader("token", jwtUserInfoToken);
		user.setKey(jwtUserInfoToken);
		// user后期需要封装几个字段，不返回user所有信息
		user.setPassword(null);
		user.setSalt(null);
		return Result.SUCCESS(Status.success).add("data", user);
	}

}
